package com.example.security.service;

import com.example.security.config.SsoClientProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 会话同步服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SessionSyncService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final SsoClientProperties ssoProperties;
    
    /**
     * 同步会话信息
     *
     * @param username 用户名
     * @param token 令牌
     */
    public void syncSession(String username, String token) {
        try {
            String sessionKey = "sso:session:" + username;
            redisTemplate.opsForHash().put(sessionKey, ssoProperties.getClientId(), token);
            redisTemplate.expire(sessionKey, ssoProperties.getToken().getExpireTime(), TimeUnit.SECONDS);
            log.debug("同步会话成功: username={}, clientId={}", username, ssoProperties.getClientId());
        } catch (Exception e) {
            log.error("同步会话失败: username=" + username, e);
            throw new RuntimeException("同步会话失败", e);
        }
    }
    
    /**
     * 移除会话信息
     *
     * @param username 用户名
     */
    public void removeSession(String username) {
        try {
            String sessionKey = "sso:session:" + username;
            redisTemplate.delete(sessionKey);
            log.debug("移除会话成功: username={}", username);
        } catch (Exception e) {
            log.error("移除会话失败: username=" + username, e);
            throw new RuntimeException("移除会话失败", e);
        }
    }

    /**
     * 获取用户在指定客户端的token
     *
     * @param username 用户名
     * @param clientId 客户端ID
     * @return token
     */
    public String getClientToken(String username, String clientId) {
        String sessionKey = "sso:session:" + username;
        Object token = redisTemplate.opsForHash().get(sessionKey, clientId);
        return token != null ? token.toString() : null;
    }

    /**
     * 判断用户是否已在其他客户端登录
     *
     * @param username 用户名
     * @return true:已登录其他客户端
     */
    public boolean isLoggedInOtherClient(String username) {
        String sessionKey = "sso:session:" + username;
        Long size = redisTemplate.opsForHash().size(sessionKey);
        return size != null && size > 0;
    }
} 